/* This class implements the Trial window frame.
 * 
 * Author: Aaron A. Lovato
 */
package gui;

import java.util.Locale;
import java.util.ResourceBundle;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;
import javax.swing.table.*;
import javax.swing.border.*;
import javax.swing.text.DefaultEditorKit;

import info.monitorenter.gui.chart.Chart2D;
import info.monitorenter.gui.chart.ITrace2D;
import info.monitorenter.gui.chart.traces.Trace2DSimple;

import core.SystemController;

public class TrialFrame extends JFrame
{
    protected ResourceBundle resbundle;
    protected AboutBox aboutBox;
    protected PrefPane prefs;
    protected Action newAction, openAction, closeAction, saveAction, saveAsAction,
    undoAction, cutAction, copyAction, pasteAction, clearAction, selectAllAction,
    preferencesAction, quitAction, aboutAction;
    protected JMenuBar mainMenuBar = new JMenuBar();
    protected JMenu fileMenu, editMenu; 

    private GridBagConstraints gbc;
    private Insets inset;
    private TrialMenuBar menuBar;
    private JPanel mainPanel;
    private Color background;

    //Results from initial modeling
    private JPanel resultPanel;
    private Border resultBorder;
    private TitledBorder equationBorder;
    private EquationTableModel equationTableModel;
    private JTable equationTable;
    private JScrollPane equationSP;
    private TitledBorder concBorder;
    private ResultTableModel concTableModel;
    private JTable concTable;
    private JScrollPane concSP;

    //Trial input
    private JPanel trialPanel;
    private Border trialBorder;
    private TitledBorder tInputBorder;
    private JPanel tInputPanel;
    private JLabel lblVolume;
    private JTextField volume;
    private JLabel lblComposition;
    private JTextField composition;
    private JLabel lblInterval;
    private JTextField interval;
    private JLabel lblCount;
    private JSpinner count;
    private SpinnerNumberModel countModel;
    private JButton modelTitration;

    //Trial output
    private JPanel tOutputPanel;
    private TitledBorder tOutputBorder;
    private JTable tResultTable;
    private JScrollPane tResultSP;
    private TrialResultTableModel tResultModel;

    //Chart
    private Chart2D chart;
    private ITrace2D trace;
    
    //Controller
    private SystemController controller;

    // Check that we are on Mac OS X.  This is crucial to loading and
    // using the OSXAdapter class.
    public static boolean MAC_OS_X = System.getProperty("os.name").startsWith("Mac OS X");

    public TrialFrame(SystemController controller)
    {
        //Set the title
        super();

        // The ResourceBundle below contains all of the strings used
        // in this application.  New localities can be added by adding
        // additional properties files.
        resbundle = ResourceBundle.getBundle ("strings", Locale.getDefault());
        setTitle(resbundle.getString("defaultProjectTitle"));
        this.controller = controller;
        background = Color.LIGHT_GRAY;

        // Set up Menu
        createActions();
        addMenus();

        setPreferredSize(new Dimension(800,400));

        //Temporary TableColumn object for resizing columns
        TableColumn column;

        //Set up the layout manager
        inset = new Insets(2,2,2,2);
        gbc = new GridBagConstraints();
        gbc.insets = inset;
        gbc.fill = GridBagConstraints.BOTH;

        //Main panel
        mainPanel = new JPanel(new GridBagLayout());
        mainPanel.setBackground(background);

        //Result panel
        resultPanel = new JPanel(new GridBagLayout());
        resultBorder = BorderFactory.createLineBorder(Color.black);
        resultPanel.setBorder(resultBorder);
        resultPanel.setBackground(background);

        //Display the resulting concentrations
        concBorder = BorderFactory.createTitledBorder("Resulting Concentrations");
        concTableModel = new ResultTableModel(controller);
        concTable = new JTable(concTableModel);
        concTable.setShowGrid(true);
        concSP = new JScrollPane(concTable);
        concSP.setPreferredSize(new Dimension(200, 100));
        concSP.setBorder(concBorder);
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 1;
        gbc.weightx = 0.5;
        gbc.weighty = 0.5;
        concSP.setBackground(background);
        resultPanel.add(concSP, gbc);

        //Display the original equations
        equationBorder = BorderFactory.createTitledBorder("System Equations");
        equationTableModel = new EquationTableModel(controller, false);
        equationTable = new JTable(equationTableModel);
        equationTable.setShowGrid(true);
        column = equationTable.getColumnModel().getColumn(0);
        column.setPreferredWidth(450);
        equationSP = new JScrollPane(equationTable);
        equationSP.setPreferredSize(new Dimension(500, 100));
        equationSP.setBorder(equationBorder);
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.gridwidth = 1;
        gbc.weightx = 0.5;
        gbc.weighty = 0.5;
        equationSP.setBackground(background);
        resultPanel.add(equationSP,gbc);

        //Add the result panel to the main panel
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 3;
        gbc.weightx = 0.5;
        gbc.weighty = 0.5;
        mainPanel.add(resultPanel, gbc);

        //Trial panel - contains titration/sweep input and outputs
        trialPanel = new JPanel(new GridBagLayout());
        trialBorder = BorderFactory.createLineBorder(Color.black);
        trialPanel.setBorder(trialBorder);

        //Titration input panel
        tInputPanel = new JPanel(new GridBagLayout());
        tInputPanel.setBackground(background);
        tInputBorder = BorderFactory.createTitledBorder("Titration");
        tInputPanel.setBorder(tInputBorder);
        lblVolume = new JLabel("Volume:");
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 0.1;
        gbc.weighty = 0.0;
        gbc.gridwidth = 1;
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
        tInputPanel.add(lblVolume, gbc);
        volume = new JTextField(5);
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.weightx = 0.5;
        tInputPanel.add(volume, gbc);
        lblComposition = new JLabel("Titrant Composition:");
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.weightx = 0.0;
        tInputPanel.add(lblComposition, gbc);
        composition = new JTextField(50);
        gbc.gridx = 1;
        gbc.weightx = 0.5;
        tInputPanel.add(composition, gbc);
        lblInterval = new JLabel("Interval:");
        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.weightx = 0.0;
        tInputPanel.add(lblInterval, gbc);
        interval = new JTextField(20);
        gbc.gridx = 1;
        gbc.weightx = 0.5;
        tInputPanel.add(interval, gbc);
        lblCount = new JLabel("Number of Intervals:");
        gbc.gridx = 0;
        gbc.gridy = 3;
        gbc.weightx = 0.0;
        tInputPanel.add(lblCount, gbc);
        countModel = new SpinnerNumberModel(10, 0, 100, 1);
        count = new JSpinner(countModel);
        gbc.gridx = 1;
        gbc.weightx = 0.5;
        tInputPanel.add(count, gbc);
        modelTitration = new JButton("Model Titration");
        gbc.gridx = 0;
        gbc.gridy = 4;
        tInputPanel.add(modelTitration, gbc);
        //Add the titration input to the trial panel
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.gridwidth = 1;
        gbc.weightx = 0.5;
        gbc.weighty = 0.5;
        trialPanel.add(tInputPanel, gbc);
        
        //Trial output panel
        tOutputPanel = new JPanel(new GridBagLayout());
        tOutputPanel.setBackground(background);
        tOutputBorder = BorderFactory.createTitledBorder("Trial Results");
        tOutputPanel.setBorder(tOutputBorder);
        String[] components = {"Component 1", "Component 2"};
        tResultModel = new TrialResultTableModel(components);
        tResultTable = new JTable(tResultModel);
        tResultTable.setShowGrid(true);
        tResultSP = new JScrollPane(tResultTable);
        tResultSP.setBackground(background);
        tOutputPanel.add(tResultSP, gbc);
        
        //Chart
        chart = new Chart2D();
        trace = new Trace2DSimple();
        trace.addPoint(0.0, 0.0);
        chart.addTrace(trace);
        gbc.gridx = 1;
        tOutputPanel.add(chart, gbc);
        
        //Add the trial output panel
        trialPanel.add(tOutputPanel, gbc);

        //Add the trial panel to the main panel
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.gridwidth = 3;
        mainPanel.add(trialPanel, gbc);

        this.add(mainPanel);
        this.pack();
    }
    
        /** Generic registration with the Mac OS X application menu
     *  Checks the platform, then attempts to register with the Apple EAWT
     *  See OSXAdapter.java to see how this is done without directly referencing any Apple APIs
     */
    public void registerForMacOSXEvents() {
        if (MAC_OS_X) {
            try {
                // Generate and register the OSXAdapter, passing it a hash of all the methods we wish to
                // use as delegates for various com.apple.eawt.ApplicationListener methods
                OSXAdapter.setQuitHandler(this, getClass().getDeclaredMethod("quit", (Class[])null));
                OSXAdapter.setAboutHandler(this, getClass().getDeclaredMethod("about", (Class[])null));
                OSXAdapter.setPreferencesHandler(this, getClass().getDeclaredMethod("preferences", (Class[])null));
            } catch (Exception e) {
                System.err.println("Error while loading the OSXAdapter:");
                e.printStackTrace();
            }
        }
    }

    
    public void about() {
        aboutBox = new AboutBox();
        aboutBox.setResizable(false);
        aboutBox.setVisible(true);
    }

    public void preferences() {
        prefs = new PrefPane();
        prefs.setResizable(false);
        prefs.setVisible(true);
    }

    public void quit() {    
        dispose();
    }

    public void createActions() {
        int shortcutKeyMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();

        // Create actions that can be used by menus, buttons, toolbars, etc.
        newAction = new newActionClass( resbundle.getString("newItem"),
                                            KeyStroke.getKeyStroke(KeyEvent.VK_N, shortcutKeyMask) );
        openAction = new openActionClass( resbundle.getString("openItem"),
                                            KeyStroke.getKeyStroke(KeyEvent.VK_O, shortcutKeyMask) );
        closeAction = new closeActionClass( resbundle.getString("closeItem"),
                                            KeyStroke.getKeyStroke(KeyEvent.VK_W, shortcutKeyMask) );
        saveAction = new saveActionClass( resbundle.getString("saveItem"),
                                            KeyStroke.getKeyStroke(KeyEvent.VK_S, shortcutKeyMask) );
        saveAsAction = new saveAsActionClass( resbundle.getString("saveAsItem") );
        undoAction = new undoActionClass( resbundle.getString("undoItem"),
                                            KeyStroke.getKeyStroke(KeyEvent.VK_Z, shortcutKeyMask) );
        cutAction = new cutActionClass( resbundle.getString("cutItem"),
                                            KeyStroke.getKeyStroke(KeyEvent.VK_X, shortcutKeyMask) );
        copyAction = new copyActionClass( resbundle.getString("copyItem"),
                                            KeyStroke.getKeyStroke(KeyEvent.VK_C, shortcutKeyMask) );
        pasteAction = new pasteActionClass( resbundle.getString("pasteItem"),
                                            KeyStroke.getKeyStroke(KeyEvent.VK_V, shortcutKeyMask) );
        clearAction = new clearActionClass( resbundle.getString("clearItem") );
        selectAllAction = new selectAllActionClass( resbundle.getString("selectAllItem"),
                                            KeyStroke.getKeyStroke(KeyEvent.VK_A, shortcutKeyMask) );
        preferencesAction = new preferencesActionClass( resbundle.getString("preferencesItem"),
                                         KeyStroke.getKeyStroke(KeyEvent.VK_COMMA, shortcutKeyMask) );
        aboutAction = new aboutActionClass( resbundle.getString("aboutItem") );
        quitAction = new quitActionClass( resbundle.getString("quitItem"),
                                         KeyStroke.getKeyStroke(KeyEvent.VK_Q, shortcutKeyMask) );
    }
    
    public void addMenus() {

        fileMenu = new JMenu(resbundle.getString("fileMenu"));
        fileMenu.add(new JMenuItem(newAction));
        fileMenu.add(new JMenuItem(openAction));
        fileMenu.add(new JMenuItem(closeAction));
        fileMenu.add(new JMenuItem(saveAction));
        fileMenu.add(new JMenuItem(saveAsAction));
        
        // These are added by default on OS X, only add on other platforms
        if(!MAC_OS_X) {
            fileMenu.add(new JMenuItem(preferencesAction));
            fileMenu.add(new JMenuItem(aboutAction));
            fileMenu.add(new JMenuItem(quitAction));
        }
        mainMenuBar.add(fileMenu);

        editMenu = new JMenu(resbundle.getString("editMenu"));
        editMenu.add(new JMenuItem(undoAction));
        editMenu.addSeparator();
        editMenu.add(new JMenuItem(cutAction));
        editMenu.add(new JMenuItem(copyAction));
        editMenu.add(new JMenuItem(pasteAction));
        editMenu.add(new JMenuItem(clearAction));
        editMenu.addSeparator();
        editMenu.add(new JMenuItem(selectAllAction));
        mainMenuBar.add(editMenu);

        setJMenuBar(mainMenuBar);
    }
    
    public class newActionClass extends AbstractAction {
        public newActionClass(String text, KeyStroke shortcut) {
            super(text);
            putValue(ACCELERATOR_KEY, shortcut);
        }
        public void actionPerformed(ActionEvent e) {
            System.out.println("New...");
        }
    }

    public class openActionClass extends AbstractAction {
        public openActionClass(String text, KeyStroke shortcut) {
            super(text);
            putValue(ACCELERATOR_KEY, shortcut);
        }
        public void actionPerformed(ActionEvent e) {
            System.out.println("Open...");
        }
    }
    
    public class closeActionClass extends AbstractAction {
        public closeActionClass(String text, KeyStroke shortcut) {
            super(text);
            putValue(ACCELERATOR_KEY, shortcut);
        }
        public void actionPerformed(ActionEvent e) {
            System.out.println("Close...");
        }
    }
    
    public class saveActionClass extends AbstractAction {
        public saveActionClass(String text, KeyStroke shortcut) {
            super(text);
            putValue(ACCELERATOR_KEY, shortcut);
        }
        public void actionPerformed(ActionEvent e) {
            System.out.println("Save...");
        }
    }
    
    public class saveAsActionClass extends AbstractAction {
        public saveAsActionClass(String text) {
            super(text);
        }
        public void actionPerformed(ActionEvent e) {
            System.out.println("Save As...");
        }
    }
    
    public class undoActionClass extends AbstractAction {
        public undoActionClass(String text, KeyStroke shortcut) {
            super(text);
            putValue(ACCELERATOR_KEY, shortcut);
        }
        public void actionPerformed(ActionEvent e) {
            System.out.println("Undo...");
        }
    }
    
    public class cutActionClass extends AbstractAction {
        protected Action cutAction;
        public cutActionClass(String text, KeyStroke shortcut) {
            super(text);
            //Use default cut support
            cutAction = new DefaultEditorKit.CutAction();
            putValue(ACCELERATOR_KEY, shortcut);
        }
        public void actionPerformed(ActionEvent e) {
            //Defer to the default cut action
            cutAction.actionPerformed(e);
        }
    }
    
    public class copyActionClass extends AbstractAction {
        protected Action copyAction;
        public copyActionClass(String text, KeyStroke shortcut) {
            super(text);
            //Use default copy support
            copyAction = new DefaultEditorKit.CopyAction();
            putValue(ACCELERATOR_KEY, shortcut);
        }
        public void actionPerformed(ActionEvent e) {
            //Defer to the default copy action
            copyAction.actionPerformed(e);
        }
    }
    
    public class pasteActionClass extends AbstractAction {
        protected Action pasteAction;
        public pasteActionClass(String text, KeyStroke shortcut) {
            super(text);
            //Use default paste support
            pasteAction = new DefaultEditorKit.PasteAction();
            putValue(ACCELERATOR_KEY, shortcut);
        }
        public void actionPerformed(ActionEvent e) {
            //Defer to the default paste action
            pasteAction.actionPerformed(e);
        }
    }
    
    public class clearActionClass extends AbstractAction {
        public clearActionClass(String text) {
            super(text);
        }
        public void actionPerformed(ActionEvent e) {
            System.out.println("Clear...");
        }
    }
    
    public class selectAllActionClass extends AbstractAction {
        public selectAllActionClass(String text, KeyStroke shortcut) {
            super(text);
            putValue(ACCELERATOR_KEY, shortcut);
        }
        public void actionPerformed(ActionEvent e) {
            System.out.println("Select All...");
        }
    }
    
    public class preferencesActionClass extends AbstractAction {
        public preferencesActionClass(String text, KeyStroke shortcut) {
            super(text);
            putValue(ACCELERATOR_KEY, shortcut);
        }
        public void actionPerformed(ActionEvent e) {
            System.out.println("Preferences");
            preferences();
        }
    }
    
    public class quitActionClass extends AbstractAction {
        public quitActionClass(String text, KeyStroke shortcut) {
            super(text);
            putValue(ACCELERATOR_KEY, shortcut);
        }
        public void actionPerformed(ActionEvent e) {
            quit();
        }
    }
    
    public class aboutActionClass extends AbstractAction {
        public aboutActionClass(String text) {
            super(text);
        }
        public void actionPerformed(ActionEvent e) {
            System.out.println("About Titrator");
            about();
        }
    }


}
